package com.lu.oss


import android.content.Context
import com.alibaba.sdk.android.oss.ClientConfiguration
import com.alibaba.sdk.android.oss.OSSClient
import com.alibaba.sdk.android.oss.common.OSSLog
import com.alibaba.sdk.android.oss.common.auth.OSSAuthCredentialsProvider
import com.alibaba.sdk.android.oss.common.auth.OSSCredentialProvider
import com.alibaba.sdk.android.oss.common.auth.OSSPlainTextAKSKCredentialProvider
import com.alibaba.sdk.android.oss.common.auth.OSSStsTokenCredentialProvider
import com.lu.oss.api.IOssService
import com.lu.oss.pojo.STSToken


/**
 *author: luqihua
 *date:2021/10/20
 *description:
 **/
class OSSClientBuilder {
    private val mBucketName: String
    private val mOssClient: OSSClient

    constructor(context: Context,
                debug: Boolean,
                bucketName: String,
                bucketEndpoint: String,
                stsToken: STSToken
    ) : this(context,
             debug,
             bucketName,
             stsToken.AccessKeyId,
             stsToken.AccessKeySecret,
             stsToken.SecurityToken,
             bucketEndpoint
    )

    constructor(context: Context,
                debug: Boolean,
                bucketName: String,
                stsServer: String,
                bucketEndpoint: String
    ) {
        // 推荐使用OSSAuthCredentialsProvider。token过期可以及时更新。
        val credentialProvider = OSSAuthCredentialsProvider(stsServer)
        mBucketName = bucketName
        mOssClient = createOSSClient(context, debug, bucketEndpoint, credentialProvider)
    }

    constructor(context: Context,
                debug: Boolean,
                bucketName: String,
                accessKeyId: String,
                secretKeyId: String,
                securityToken: String,
                bucketEndpoint: String
    ) {
        // 推荐使用OSSAuthCredentialsProvider。token过期可以及时更新。
        val credentialProvider = OSSStsTokenCredentialProvider(
                accessKeyId,
                secretKeyId,
                securityToken
        )
        mBucketName = bucketName
        mOssClient = createOSSClient(context, debug, bucketEndpoint, credentialProvider)
    }

    constructor(context: Context,
                debug: Boolean,
                bucketName: String,
                accessKeyId: String,
                secretKeyId: String,
                bucketEndpoint: String
    ) {
        // 推荐使用OSSAuthCredentialsProvider。token过期可以及时更新。
        val credentialProvider = OSSPlainTextAKSKCredentialProvider(
                accessKeyId,
                secretKeyId,
        )
        mBucketName = bucketName
        mOssClient = createOSSClient(context, debug, bucketEndpoint, credentialProvider)
    }

    private fun createOSSClient(
            context: Context,
            debug: Boolean,
            bucketEndpoint: String,
            provider: OSSCredentialProvider
    ): OSSClient {
        // 配置类如果不设置，会有默认配置。
        if (debug) {
            OSSLog.enableLog()
        }
        return OSSClient(
                context.applicationContext,
                bucketEndpoint,
                provider,
                getConfig()
        )
    }

    private fun getConfig() = ClientConfiguration().apply {
        connectionTimeout = 15 * 1000; // 连接超时，默认15秒。
        socketTimeout = 15 * 1000; // socket超时，默认15秒。
        maxConcurrentRequest = 5; // 最大并发请求数，默认5个。
        maxErrorRetry = 2; // 失败后最大重试次数，默认2次。
    }

    fun build(): IOssService {
        return OssServiceImpl(mBucketName, mOssClient)
    }
}